// Copyright (c) 2007 Robin Boerdijk. All rights reserved.
//
// This software is licensed under the terms of the Microsoft Reciprocal License as described 
// in the file LICENSE.txt, which you should have received as part of this distribution. The 
// license terms are also available at http://www.opensource.org/licenses/ms-rl.html.

#ifndef wtk_Geometry_h_included
#define wtk_Geometry_h_included

#include <windows.h>

namespace wtk
{
	//--- Set/Construct(long) ---//

	inline void Set(RECT &rect, long leftTopRightBottom)
	{
		rect.left = leftTopRightBottom;
		rect.top = leftTopRightBottom;
		rect.right = leftTopRightBottom;
		rect.bottom = leftTopRightBottom;
	}

	//--- Set/Construct(long, long) ---//

	inline void Set(POINT &point, long x, long y) 
	{ 
		point.x = x; 
		point.y = y; 
	}

	inline void Set(SIZE &size, long cx, long cy) 
	{ 
		size.cx = cx; 
		size.cy = cy; 
	}

	inline void Set(RECT &rect, long leftRight, long topBottom)
	{
		rect.left = leftRight;
		rect.top = topBottom;
		rect.right = leftRight;
		rect.bottom = topBottom;
	}

	template<typename T> inline T Construct(long a, long b) { T r; Set(r, a, b); return r; }

	//--- Set/Construct(long, long, long, long) ---//

	inline void Set(RECT &rect, long left, long top, long right, long bottom) 
	{ 
		rect.left = left; 
		rect.top = top; 
		rect.right = right; 
		rect.bottom = bottom; 
	}

	template<typename T> inline T Construct(long a, long b, long c, long d) { T r; Set(r, a, b, c, d); return r; }

	//--- Init/Construct(const T2 &) ---//

	inline void Set(SIZE &size, const RECT &rect)
	{
		size.cx = rect.right - rect.left;
		size.cy = rect.bottom - rect.top;
	}

	inline void Set(RECT &rect, const SIZE &size)
	{
		Set(rect, 0, 0, size.cx, size.cy);
	}

	template<typename T1, typename T2> inline T1 Construct(const T2 &a) { T1 r; Set(r, a); return r; }

	//--- Zero ---//

	template<typename T> inline T Zero();

	template<> inline POINT Zero<POINT>() 
	{ 
		return Construct<POINT>(0, 0); 
	}

	template<> inline SIZE Zero<SIZE>() 
	{ 
		return Construct<SIZE>(0, 0); 
	}
	
	template<> inline RECT Zero<RECT>() 
	{ 
		return Construct<RECT>(0, 0, 0, 0);
	}

	//--- Invalid/IsInvalid ---//

	template<typename T> inline T Invalid();
	
	template<> inline SIZE Invalid<SIZE>() 
	{ 
		return Construct<SIZE>(-1, -1);
	}

	template<typename T> inline bool IsInvalid(const T &value);

	template<> inline bool IsInvalid<SIZE>(const SIZE &size) 
	{ 
		return (size.cx < 0) || (size.cy < 0); 
	}

	POINT GetDefaultWindowPosition(const SIZE &windowSize, const RECT &containerRect);
}

#endif